package com.xiaoshuidi.cloud.module.member.service.securitycheck;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.module.member.enums.RectificationItemStatusEnum;
import com.xiaoshuidi.cloud.module.member.mapper.securitycheck.SecurityCheckMapper;
import com.xiaoshuidi.cloud.module.member.mapper.securitycheck.SecurityCheckRectificationItemMapper;
import com.xiaoshuidi.cloud.module.member.pojo.securitycheck.SecurityCheckDO;
import com.xiaoshuidi.cloud.module.member.pojo.securitycheck.SecurityCheckRectificationFileDO;
import com.xiaoshuidi.cloud.module.member.pojo.securitycheck.SecurityCheckRectificationItemDO;
import com.xiaoshuidi.cloud.module.system.api.user.AdminUserApi;
import com.xiaoshuidi.cloud.module.system.api.user.dto.AdminUserRespDTO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import com.xiaoshuidi.cloud.module.member.controller.admin.securitycheck.vo.*;

import com.xiaoshuidi.cloud.module.member.convert.securitycheck.SecurityCheckConvert;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.member.enums.ErrorCodeConstants.*;

/**
 * 安全检查 Service 实现类
 *
 * @author hans.zhang
 */
@Service
@Validated
public class SecurityCheckServiceImpl extends ServiceImpl<SecurityCheckMapper, SecurityCheckDO> implements SecurityCheckService {

    @Resource
    private SecurityCheckMapper securityCheckMapper;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private SecurityCheckRectificationFileService securityCheckRectificationFileService;
    @Resource
    private SecurityCheckRectificationItemMapper securityCheckRectificationItemMapper;

    @Override
    public Long createSecurityCheck(SecurityCheckCreateReqVO createReqVO) {
        // 插入
        SecurityCheckDO securityCheck = SecurityCheckConvert.INSTANCE.convert(createReqVO);
        securityCheck.setIsPlaceOnFile(false);
        securityCheckMapper.insert(securityCheck);
        // 返回
        return securityCheck.getId();
    }

    @Override
    public void updateSecurityCheck(SecurityCheckUpdateReqVO updateReqVO) {
        // 校验存在
        validateSecurityCheckExists(updateReqVO.getId());
        // 更新
        SecurityCheckDO updateObj = SecurityCheckConvert.INSTANCE.convert(updateReqVO);
        securityCheckMapper.updateById(updateObj);
    }

    @Override
    public void deleteSecurityCheck(Long id) {
        // 校验存在
        validateSecurityCheckExists(id);
        // 删除
        securityCheckMapper.deleteById(id);
    }

    private void validateSecurityCheckExists(Long id) {
        if (securityCheckMapper.selectById(id) == null) {
            throw exception(SECURITY_CHECK_NOT_EXISTS);
        }
    }

    @Override
    public SecurityCheckDO getSecurityCheck(Long id) {
        return securityCheckMapper.selectById(id);
    }

    @Override
    public List<SecurityCheckDO> getSecurityCheckList(Collection<Long> ids) {
        return securityCheckMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<SecurityCheckRespVO> getSecurityCheckPage(SecurityCheckPageReqVO pageReqVO) {
        QueryWrapper<SecurityCheckDO> wrapper = Wrappers.query();
        wrapper.eq("msc.deleted", false);
        wrapper.and(ObjectUtil.isNotEmpty(pageReqVO.getSearchBox()), wrap -> wrap.like("mscp.name", pageReqVO.getSearchBox())
                .or().like("mscp.check_work_unit", pageReqVO.getSearchBox())
                .or().like("msc.inspectorate", pageReqVO.getSearchBox())
        );
        wrapper.between(ObjectUtil.isAllNotEmpty(pageReqVO.getCheckDateStart(), pageReqVO.getCheckDateEnd()), "msc.check_date", pageReqVO.getCheckDateStart(), pageReqVO.getCheckDateEnd());
        wrapper.orderByAsc("msc.is_place_on_file");
        wrapper.orderByDesc("msc.create_time");
        Page<SecurityCheckRespVO> page = securityCheckMapper.page(new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), wrapper);

        List<SecurityCheckRespVO> records = page.getRecords();
        List<Long> creatorIds = records.stream().map(p->Long.valueOf(p.getCreator())).distinct().collect(Collectors.toList());
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(creatorIds);
        List<Long> wilfulnessIds = records.stream().map(SecurityCheckBaseVO::getWilfulness).distinct().collect(Collectors.toList());
        Map<Long, AdminUserRespDTO> wilfulnessUserMap = adminUserApi.getUserMap(wilfulnessIds);

        page.getRecords().forEach(securityCheckRespVO -> {
            Long creator = Long.valueOf(securityCheckRespVO.getCreator());
            if(ObjectUtil.isNotEmpty(creator) && userMap.containsKey(creator)){
                AdminUserRespDTO checkedData = userMap.get(creator);
                securityCheckRespVO.setCreatorName(checkedData.getNickname());
            }
            Long wilfulness = securityCheckRespVO.getWilfulness();
            if(ObjectUtil.isNotEmpty(wilfulness) && wilfulnessUserMap.containsKey(wilfulness)){
                AdminUserRespDTO checkedData = wilfulnessUserMap.get(wilfulness);
                securityCheckRespVO.setWilfulnessName(checkedData.getNickname());
            }
        });
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    @Override
    public List<SecurityCheckDO> getSecurityCheckList(SecurityCheckExportReqVO exportReqVO) {
        return securityCheckMapper.selectList(exportReqVO);
    }

    @Override
    public SecurityCheckDO myGetById(Long id) {
        SecurityCheckDO securityCheckDO = securityCheckMapper.selectById(id);
        if(ObjectUtil.isEmpty(securityCheckDO)){
            throw exception(SECURITY_CHECK_NOT_EXISTS);
        }
        return securityCheckDO;
    }

    @Override
    public Boolean pigeonhole(Long id) {
        SecurityCheckDO securityCheckDO = securityCheckMapper.selectById(id);
        if(ObjectUtil.isEmpty(securityCheckDO)){
            throw exception(SECURITY_CHECK_NOT_EXISTS);
        }
        // 检查是否存在未完成的整改项
        LambdaQueryWrapper<SecurityCheckRectificationItemDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SecurityCheckRectificationItemDO::getSecurityCheckId, id);
        List<SecurityCheckRectificationItemDO> securityCheckRectificationItemDOS = securityCheckRectificationItemMapper.selectList(wrapper);
        SecurityCheckRectificationItemDO securityCheckRectificationItemDO = securityCheckRectificationItemDOS.stream().filter(p -> RectificationItemStatusEnum.PENDING.getCode().equals(p.getStatus())).findFirst().orElse(null);
        if(ObjectUtil.isNotEmpty(securityCheckRectificationItemDO)){
            throw exception(SECURITY_CHECK_ITEM_EXISTS_PENDING);
        }
        securityCheckDO.setIsPlaceOnFile(true);
        securityCheckMapper.updateById(securityCheckDO);
        return Boolean.TRUE;
    }

    /**
     * 上传整改文件
     *
     * @param loginUserName
     * @param securityCheckId
     * @param fileUrl
     * @param fileType
     * @return
     */
    @Override
    public Long uploadRectificationFile(String loginUserName, Long securityCheckId, String fileUrl, String fileType) {
        // 检查是否已经归档
        SecurityCheckDO securityCheckDO = securityCheckMapper.selectById(securityCheckId);
        if(ObjectUtil.isEmpty(securityCheckDO)){
            throw exception(SECURITY_CHECK_NOT_EXISTS);
        }
        if(securityCheckDO.getIsPlaceOnFile()){
            throw exception(SECURITY_CHECK_IS_PLACE_ON_FILE);
        }
        // 保存文件链接
        SecurityCheckRectificationFileCreateReqVO createReqVO = new SecurityCheckRectificationFileCreateReqVO();
        createReqVO.setSecurityCheckId(securityCheckId);
        createReqVO.setUserName(loginUserName);
        createReqVO.setFileUrl(fileUrl);
        createReqVO.setFileType(fileType);
        return securityCheckRectificationFileService.createSecurityCheckRectificationFile(createReqVO);
    }

    /**
     * 删除整改文件
     *
     * @param rectificationFileId 整改文件id
     * @param securityCheckId
     * @return
     */
    @Override
    public Boolean rectificationFileDelete(Long rectificationFileId, Long securityCheckId) {
        // 检查是否已经归档
        SecurityCheckDO securityCheckDO = securityCheckMapper.selectById(securityCheckId);
        if(ObjectUtil.isEmpty(securityCheckDO)){
            throw exception(SECURITY_CHECK_NOT_EXISTS);
        }
        if(securityCheckDO.getIsPlaceOnFile()){
            throw exception(SECURITY_CHECK_IS_PLACE_ON_FILE);
        }
        return securityCheckRectificationFileService.deleteSecurityCheckRectificationFile(rectificationFileId);
    }

    /**
     * 整改文件分页
     *
     * @param securityCheckId
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<SecurityCheckRectificationFileDO> rectificationFilePage(Long securityCheckId, Integer pageNo, Integer pageSize) {
        return securityCheckRectificationFileService.getSecurityCheckRectificationFilePage(securityCheckId, pageNo, pageSize);
    }

    /**
     * 检查是否已归档
     * @param securityCheckId
     * @return
     */
    @Override
    public void checkIsPlaceOnFile(Long securityCheckId) {
        // 检查是否已经归档
        SecurityCheckDO securityCheckDO = securityCheckMapper.selectById(securityCheckId);
        if(ObjectUtil.isEmpty(securityCheckDO)){
            throw exception(SECURITY_CHECK_NOT_EXISTS);
        }
        if(securityCheckDO.getIsPlaceOnFile()){
            throw exception(SECURITY_CHECK_IS_PLACE_ON_FILE);
        }
    }

}
